# constructProj/jsonConfig.py
# -*-coding:utf-8 -*-
# @file       jsonConfig.py
# @author     yearnext
# @version    1.0.0
# @date       2021-11-19
# @brief      constructProj jsonConfig.py component
import os
import sys
import traceback
import re
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSerialPort import *
from moudles.ui.SerialConfig import uiSerialConfig
from moudles.tool import tLog


class SerialConfigWidget(QtWidgets.QWidget, uiSerialConfig):
    sigOpen = pyqtSignal(str, int, int, int, int)
    sigClose = pyqtSignal(str)

    def __init__(self, argv, parent=None):
        super().__init__(parent)

        # UI初始化
        self.uiInit()

        # 输入参数初始化
        self.inputParamInit(argv)

        # 串口初始化
        self.serialPortInit()

        # 信号槽初始化
        self.signalSoltInit()

    # UI初始化
    def uiInit(self):
        # UI 初始化
        self.setupUi(self)

    # 输入参数初始化
    def inputParamInit(self, argv):
        tLog.putFuncArg(argv)

    def serialPortInit(self):
        self.curPort = 'None'
        self.curBaud = 115200
        self.curDataBits = 8
        self.curStopBits = 1
        self.curParityBits = 0

        self.setPortStatus(0)
        self.portListInit()
        self.portBaudInit()
        self.portDataBitsInit()
        self.portStopBitsInit()
        self.portParityInit()

    def signalSoltInit(self):
        print('signal solt init')

        self.activeButton.clicked.connect(self.portActiveProcess)
        self.portComboBox.currentTextChanged.connect(self.portNameChangedProcess)
        self.portComboBox.clicked.connect(self.portListInit)

    ####################################################################################################################
    # 端口参数初始化
    ####################################################################################################################
    def portListInit(self):
        # 检测所有存在的串口，将信息存储在字典中
        self.portComboBox.clear()
        port_list = QSerialPortInfo.availablePorts()
        tempList = []
        nameTempList = []
        # print(self.port_list)
        if len(port_list) == 0:
            self.portComboBox.addItem('None')
        else:
            for port in port_list:
                name = port.portName().upper() + '-' + port.description()
                tempList.append(re.split(u'^(COM)([0-9]*)(-)*', name))

            # print(tempList)
            tempList.sort(key=self.getPortNameId)
            # print(tempList)

            for i in tempList:
                name = ''
                # print('i', i)
                for j in i:
                    # print('j', j)
                    if len(j):
                        name += j
                self.portComboBox.addItem(name)
            self.portComboBox.setCurrentIndex(0)

    def portBaudInit(self):
        self.baudComboBox.clear()
        baudList = QSerialPortInfo.standardBaudRates()
        baudList.append(460800)
        baudList.append(500000)
        baudList.append(512000)
        baudList.append(750000)
        baudList.append(921600)
        baudList.append(1000000)
        baudList.append(1500000)
        baudList.append(2000000)

        for i in baudList:
            self.baudComboBox.addItem(str(i))

        self.baudComboBox.setCurrentText(str(115200))

    def portDataBitsInit(self):
        self.dataBitComboBox.clear()
        temp = [5, 6, 7, 8]

        for i in temp:
            self.dataBitComboBox.addItem(str(i))

        self.dataBitComboBox.setCurrentText('8')

    def portStopBitsInit(self):
        self.stopBitComboBox.clear()
        temp = [1, 1.5, 2]

        for i in temp:
            self.stopBitComboBox.addItem(str(i))

        self.stopBitComboBox.setCurrentText('1')

    def portParityInit(self):
            self.parityComboBox.clear()
            temp = [u'None', u'奇校验', u'偶校验']

            for i in temp:
                self.parityComboBox.addItem(i)

            self.parityComboBox.setCurrentText('None')

    ####################################################################################################################
    # 端口参数转换
    ####################################################################################################################
    def baudConfig2Num(self):
        if self.baudComboBox.currentText().isdigit():
            return int(self.baudComboBox.currentText())
        return 115200

    def dataBitsConfig2Num(self):
        if self.dataBitComboBox.currentText() == '5':
            return QSerialPort.Data5
        elif self.dataBitComboBox.currentText() == '6':
            return QSerialPort.Data6
        elif self.dataBitComboBox.currentText() == '7':
            return QSerialPort.Data7
        else:
            return QSerialPort.Data8

    def stopBitsConfig2Num(self):
        if self.stopBitComboBox.currentText() == '1.5':
            return QSerialPort.OneAndHalfStop
        elif self.stopBitComboBox.currentText() == '2':
            return QSerialPort.TwoStop
        else:
            return QSerialPort.OneStop

    def parityConfig2Num(self):
        if self.parityComboBox.currentIndex() == 1:
            return QSerialPort.OddParity
        elif self.parityComboBox.currentIndex() == 2:
            return QSerialPort.EvenParity
        else:
            return QSerialPort.NoParity

    def getPortNameId(self, elem):
        # print(elem)
        for i in range(0, len(elem)):
            if elem[i].isdigit():
                # print(i, elem[i])
                return int(elem[i])
        # print(0)
        return 0

    def portIndex2Name(self):
        portName = self.portComboBox.currentText()

        if portName != u'None':
            temp = re.split(u'^(COM)([0-9]*)(-)*', portName)
            # print(portName, temp)
            return 'COM{0}'.format(self.getPortNameId(temp))

        return portName

    ####################################################################################################################
    # 槽函数
    ####################################################################################################################
    def portNameChangedProcess(self, text:str):
        if self.activeButton.text() == u'关闭串口' and self.curPort != self.portComboBox.currentText():
            print('port name changed, curName:{0}, newNam:{1}:', self.curPort, text)
            self.sigClose.emit(self.curPort)

    def portActiveProcess(self):
        portName = self.portIndex2Name()

        # print('portActiveProcess', portName)

        if portName == u'None':
            return

        if self.activeButton.text() == u'打开串口':
            self.curPort       = portName
            self.curBaud       = self.baudConfig2Num()
            self.curDataBits   = self.dataBitsConfig2Num()
            self.curStopBits   = self.stopBitsConfig2Num()
            self.curParityBits = self.parityConfig2Num()
            self.sigOpen.emit(self.curPort, self.curBaud, self.curDataBits, self.curStopBits, self.curParityBits)
        else:
            self.sigClose.emit(portName)

    ####################################################################################################################
    # 外部接口调用
    ####################################################################################################################
    def setPortStatus(self, status:int):
        # tLog.putInfo('status:{0}'.format(status))
        if status == 1:
            self.activeButton.setText(u'关闭串口')
            self.portStatus.setOn()
        elif status == -1:
            self.activeButton.setText(u'打开串口')
            self.portStatus.blink(250, 250, -1)
        elif status == 0:
            self.activeButton.setText(u'打开串口')
            self.portStatus.setOff()
        else:
            self.activeButton.setText(u'打开串口')
            self.portStatus.setOff()

# if __name__ == '__main__':
#     app = QtWidgets.QApplication(sys.argv)
#     window = SerialConfigWidget(sys.argv)
#     window.show()
#     sys.exit(app.exec_())
